import {AxiosRequestConfig, AxiosPromise, AxiosResponse} from '../types';
import {buildURL} from '../helpers/url';
import xhr from './xhr';
import { transformRequest, transformResponse} from '../helpers/data';
import {flattenHeaders, processHeaders} from '../helpers/headers';
import transform from '../helpers/transform';

export default function dispatchRequest (config: AxiosRequestConfig): AxiosPromise {
  processConfig(config)
  return xhr(config).then(res => transformResponseData(res));
}

function processConfig (config: AxiosRequestConfig): void {
  config.url = transformUrl(config)
  config.headers = transformHeaders(config);
  config.data = transform(config.data, config.headers, config.transformRequest);
  config.headers = flattenHeaders(config.headers, config.method!);
}

function transformUrl (config: AxiosRequestConfig): string {
  const { url, params } = config
  return buildURL(url, params)
}

function transformRequestData (config: AxiosRequestConfig): any {
  return transformRequest(config.data);
}

function transformResponseData (res: AxiosResponse): AxiosResponse {
  res.data = transform(res.data, res.headers, res.config.transformResponse);
  return res;
}

function transformHeaders (config: AxiosRequestConfig) {
  const {headers = {}, data} = config;
  return processHeaders(headers, data);
}